﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Duellum.Core;
using JpLabs.Extensions;
using JpLabs.Geometry;
using Duellum.Map;
using System.Windows;

namespace Duellum.Game.Commands
{
	internal class TurnCommand : IDuelCommand
	{
		private readonly AngleCmdParam angleParam;
		private readonly PositionCmdParam positionParam;
		private readonly DuelGame game;
		
		public TurnCommand(DuelGame game)
		{
			this.game = game;
			
			angleParam = new AngleCmdParam();
			positionParam = new PositionCmdParam();
		}
		
		DuelTypeId IDuelCommand.Id
		{
			get { return DuelCoreCommands.Turn; }
		}

		public bool CanExecute(IEnumerable<object> values)
		{
			double angle;
			
			if (!TryValidateValues(values, out angle)) return false;
			
			//No particular validation to make			
			return true;
		}
		
		private bool TryValidateValues(IEnumerable<object> values, out double outAngle)
		{
			outAngle = default(double);
			
			if (values == null) return false;
			object value;
			if (!values.TrySingle(out value)) return false;
			
			PointInt targetPosition;
			if (positionParam.TryCoerceValue(value, out targetPosition))
			{
				var playerPosition = game.CurrentPlayer.Position.Value;
				
				outAngle = DuelMap.AngleBetwen(playerPosition, targetPosition);
				
				return true;
			}
			
			return angleParam.TryCoerceValue(value, out outAngle);
		}

		public IDuelActionSequence Execute(IEnumerable<object> values)
		{
			double angle;
			
			if (!TryValidateValues(values, out angle)) throw new ArgumentException();
			
			//TODO: break TurnCommand into several single-step TurnActions
			
			game.CurrentPlayer.FaceAngle = angle;
			
			return null;
		}
	}
}
